<template>
  <van-dialog v-model="show" class="print-dialog" show-cancel-button title="请填写打印参数" :before-close="beforClosePrint" confirm-button-text="打印" confirm-button-color="#518CF6" @cancel="handleCancelPrint" @confirm="handleConfirmPrint">
    <el-form ref="printForm" :model="printForm" class="printForm" :rules="printFormRule" label-width="110px" @submit.native.prevent>
      <el-form-item label="打印机：" prop="connectedBluetooth">
        <el-select v-model="printForm.connectedBluetooth" placeholder="请选择打印机">
          <el-option v-for="(print, printIndex) in printList" :key="printIndex" :label="print.name" :value="print.name" @click.native="changeConnectedBluetooth(print)" />
        </el-select>
      </el-form-item>
      <el-form-item label="选择模板：" prop="ruleId">
        <el-select v-model="printForm.ruleId" clearable placeholder="请选择模板">
          <el-option v-for="(item, index) in [templateInfo]" :key="index" :label="item.ruleName" :value="item.ruleId" />
        </el-select>
      </el-form-item>
      <el-form-item label="打印数量：" prop="num">
        <el-input type="number" v-model="printForm.num" placeholder="请输入打印数量" />
      </el-form-item>
      <el-form-item label="批次号：" prop="batch">
        <el-input v-model="printForm.batch" :disabled="!this.materialInfo.materialEntity.isBatchMag" placeholder="请输入批次号" />
      </el-form-item>
      <el-form-item label="实际数量：" prop="actualNum">
        <el-input type="number" v-model="printForm.actualNum" placeholder="请输入实际入库数量" />
      </el-form-item>
      <el-form-item label="打印机指令：" prop="printerInstruction">
        <el-select v-model="printForm.printerInstruction" placeholder="请选择打印机">
          <el-option v-for="(instruction, instructionIndex) in printerInstructionOptions" :key="instructionIndex" :label="instruction.label" :value="instruction.value" />
        </el-select>
      </el-form-item>
    </el-form>
  </van-dialog>
</template>
<script>
import Vue from "vue";
import CommonHeader from "@/components/CommonHeader/index.vue";
import CommonMain from "@/components/CommonMain/index.vue";
import { Toast, Dialog } from "vant";
import { setConnectedBluetooth,getConnectedBluetooth,setCurrentConnectedBluetoothList,getCurrentConnectedBluetoothList } from "@/utils/auth";
import { codeType, inventoryBatchPrint, materialPrint } from "@/api/inventory";
import { reqLabelTypes, reqPrintLabelType, reqBarcode } from "@/api/cj.js";
import lodash from "lodash";
import { setPrintInstruction, getPrintInstruction } from "@/utils/auth";
import * as Interface from "@/utils/jingzhi";
import { cloneDeep } from "lodash";
Vue.use(Toast);
const printConfig = {
  lines: 1,
  gap: 2,
  width: 30,
  column: 3,
  columns: 1,
  height: 10,
  command: "TSPL",
};
const printTemplateObj = {
  index: 0,
  height: 15,
  width: 15,
  paperHeader: 0,
  paperFooter: -1,
  printElements: [
    {
      options: {
        left: 9,
        top: 7.5,
        height: 20,
        width: 20,
        field: "custom_qrcode",
        testData: "88888888",
        textType: "qrcode",
        title: "custom_qrcode",
        right: 28.25,
        bottom: 26.75,
        vCenter: 18.25,
        hCenter: 16.75,
        coordinateSync: false,
        widthHeightSync: false,
      },
      printElementType: {
        title: "{二维码}",
        type: "text",
      },
    },
  ],
  paperNumberLeft: 12,
  paperNumberTop: 20,
  gap: 2,
  column: 1,
  dpi: 203,
  columns: 1,
  lines: 1,
  direction: 0,
};
export default {
  components: {
    CommonHeader,
    CommonMain,
  },
  data() {
    const validateBatch = (rule, value, callback) => {
      const isBatchMag = this.materialInfo.materialEntity.isBatchMag;
      if (isBatchMag && String(value).length === 0) {
        callback(new Error('请输入批次号'));
      } else {
        callback();
      }
    };
    return {
      codeList: [],
      printList: [],
      printForm: {
        connectedBluetooth: "",
        num: 1,
        printerInstruction: "TSPL",
        batch: "",
        actualNum: 1,
        ruleId: "",
      },
      printFormRule: {
        connectedBluetooth: [
          {
            required: true,
            message: "该参数是必填项",
            trigger: ["blur", "change"],
          },
        ],
        ruleId: [
          {
            required: true,
            message: "该参数是必填项",
            trigger: ["blur"],
          },
        ],
        num: [
          {
            required: true,
            message: "该参数是必填项",
            trigger: ["blur", "change"],
          },
          {
            pattern: /(^[1-9]\d{0,9}$)/,
            message: "输入1-9的数字",
          },
        ],
        actualNum: [
          {
            required: true,
            message: "该参数是必填项",
            trigger: ["blur", "change"],
          },
        ],
        printerInstruction: [
          {
            required: true,
            message: "该参数是必填项",
            trigger: ["blur", "change"],
          },
        ],
        batch:[{validator: validateBatch, trigger: 'blur'}]
      },
      currentPrint: "",
      fullscreenLoading: false,
      printerInstructionOptions: [
        { label: "TSPL(TSC)", value: "TSPL" },
        { label: "ZPL(斑马)", value: "ZPL" },
      ],
      pageType: "temporaryCodePrinting",
      deviceAllList: [],
      wiredDeviceList: [],
      show: this.isShowPrint,
      templateInfo: {}, //采购入库物料打印模板
    };
  },
  props: {
    isShowPrint: {
      type: Boolean,
      default: false,
    },
    materialInfo: {
      type: Object,
      default: () => ({}),
    },
  },
  watch: {
    materialInfo: {
      async handler(newValue, oldValue) {
        this.printForm.actualNum = newValue.planAmount;
        const relateOrders = newValue.relateOrders;
        const materialCode = newValue.materialEntity.code;
        const isBatchMag = newValue.materialEntity.isBatchMag;
        if (isBatchMag) {
          this.printForm.batch = await this.getBatchCode(relateOrders,materialCode);
        }
      },
      immediate: true,
      deep: true,
    },
  },
  created() {
    Interface.startDiscovery();
    this.getwiredDeviceList("init");
    // 获取本地缓存打印机指令
    const printInstruction = getPrintInstruction();
    if (printInstruction) {
      this.printForm.printerInstruction = printInstruction;
    }
  },
  mounted() {
    this.getLabelTypes();
    // this.autoConnectPrint()
    // 无线设备
    window.startDiscovery = (device) => {
      this.deviceAllList.push(device);
      this.filterDeviceList();
    };
    // 无线设备断开监听 删除已记录的连接设备
    window.bluetoothPrintstate = (device, type) => {
      if (type === 2) {
        this.deleteConnectDeviceRecord();
      }
    };
  },
  methods: {
    async getCodeList() {
      const params = { codeType: "WarehouseBarCodeNumber" };
      const reslut = await codeType(params);
      const { data, code } = reslut.data;
      if (code != 200) {
        return;
      }
      this.codeList = data.records;
    },
    //获取标签模板
    getLabelTypes() {
      reqLabelTypes().then(
        (response) => {
          if (response.code === 200 && response.data) {
            const templateInfo = response.data;
            this.templateInfo = templateInfo;
            this.printForm.ruleId = templateInfo.ruleId;
          }
          console.log("获取标签模板api", response);
        },
        (error) => {
          console.log("获取标签模板api", error);
        }
      );
    },
    //获取打印模板
    getPrintLabelTypes(materialCode, batchCode, quantity) {
      const { ruleId, ruleCode, content } = this.templateInfo;
      const parameter = {
        ruleId: ruleId,
        printCodes: "",
        ruleCode: ruleCode,
        ruleType: "",
        printLabelDetailDTO: {
          materialCode: materialCode,
          quantity: quantity,
          barCode: batchCode,
        },
      };
      return new Promise((resolve, reject) => {
        reqPrintLabelType(parameter).then(
          (response) => {
            if (response.code === 200 && response.data) {
              //
              resolve(response);
            }
            console.log("获取打印模板api", response);
          },
          (error) => {
            console.log("获取打印模板api", error);
            reject(error);
          }
        );
      });
    },
    // 删除连接记录
    async deleteConnectDeviceRecord(device, type) {
      if (type === "BluetoothClose") {
        // 关闭蓝牙连接
        await Interface.BluetoothClose(device); // 关闭蓝牙连接
      }
      const currentConnectedBluetoothStr = getCurrentConnectedBluetoothList();
      if (currentConnectedBluetoothStr) {
        const list = JSON.parse(currentConnectedBluetoothStr);
        const tempList = list.filter((item) => item.address !== device.address);
        setCurrentConnectedBluetoothList(JSON.stringify(tempList));
      }
    },
    // 过滤打印机设备
    filterDeviceList() {
      const res = new Map();
      this.printList = this.deviceAllList.filter((a) => !res.has(a.name) && res.set(a.name, 1) && a.type != 4);
    },
    // 自动连接打印机
    async autoConnectPrint() {
      const connectedStr = getConnectedBluetooth();
      if (connectedStr) {
        const connectedList = JSON.parse(connectedStr);
        const index = connectedList.findIndex(
          (item) => item.type === this.pageType
        );
        if (index !== -1) {
          const connectedDevice = connectedList[index].connectedDevice;
          // 存在连接记录
          if (connectedDevice) {
            const tempObj = connectedDevice.usbName
              ? this.wiredDeviceList.find(
                  (item) =>
                    item.vendorId === connectedDevice.vendorId &&
                    item.productId === connectedDevice.productId
                )
              : connectedDevice;
            if (!tempObj) {
              // 有线设备没有获取到数据则不连接
              // this.$message({
              //   message: `未获取到已连接过的有线设备`,
              //   type: 'warning'
              // })
              return;
            }
            const reslut = connectedDevice.usbName
              ? await Interface.connectUsb(tempObj)
              : await Interface.ConnectionStatus(tempObj);
            if (reslut) {
              // 已连接上打印机
              this.printForm.connectedBluetooth = connectedDevice.name;
              this.currentPrint = connectedDevice;
              // 避免已连接的无线设备获取不到的问题
              if (!connectedDevice.usbName) {
                const temp = this.printList.find(
                  (item) => item.address === connectedDevice.address
                );
                if (!temp) {
                  this.deviceAllList.push(connectedDevice);
                  this.filterDeviceList();
                }
              }
            } else {
              // 未连接上则自动连接
              this.changeConnectedBluetooth(connectedDevice);
            }
          }
        }
      }
    },
    // 缓存连接设备
    setConnectedList(val) {
      const connectedStr = getConnectedBluetooth();
      if (connectedStr) {
        const connectedList = JSON.parse(connectedStr);
        const index = connectedList.findIndex(
          (item) => item.type === this.pageType
        );
        if (index !== -1) {
          connectedList[index].connectedDevice = val;
        } else {
          connectedList.push({ type: this.pageType, connectedDevice: val });
        }
        setConnectedBluetooth(JSON.stringify(connectedList));
      } else {
        setConnectedBluetooth(
          JSON.stringify([{ type: this.pageType, connectedDevice: val }])
        );
      }
      if (!val.usbName) {
        const currentConnectedBluetoothStr = getCurrentConnectedBluetoothList();
        let list = [];
        if (currentConnectedBluetoothStr) {
          list = JSON.parse(currentConnectedBluetoothStr);
          list.push(val);
        } else {
          list = [val];
        }
        setCurrentConnectedBluetoothList(JSON.stringify(list)); // 无线设备时保存当前连接设备
      }
    },
    // 选择打印机
    // 获取打印机列表
    getPrintList() {
      this.deviceAllList = [];
      this.printList = [];
      // 无线设备已连接设备需要放进列表
      const currentConnectedBluetoothStr = getCurrentConnectedBluetoothList();
      if (currentConnectedBluetoothStr) {
        const list = JSON.parse(currentConnectedBluetoothStr);
        this.deviceAllList.push(...list);
      }
      Interface.startDiscovery(); // 无线设备
      this.getwiredDeviceList();
    },
    // 获取有线设备
    async getwiredDeviceList(type) {
      const reslut = await Interface.getUsbDevice(); // 有线设备
      if (reslut) {
        this.wiredDeviceList = reslut || [];
        const tempList = reslut.map((item) => {
          return {
            ...item,
            name: `${item.vendorId}-${item.productId}`,
            deviceType: "wired",
          };
        });
        this.deviceAllList.push(...tempList);
        this.filterDeviceList();
      }
      type === "init" && this.autoConnectPrint();
    },
    // 选中打印设备
    async changeConnectedBluetooth(val, current) {
      this.fullscreenLoading = true;
      try {
        const reslut = val.usbName
          ? await Interface.connectUsb(
              this.wiredDeviceList.find(
                (item) =>
                  item.vendorId === val.vendorId &&
                  item.productId === val.productId
              )
            )
          : await Interface.BluetoothConnection(val);
        if (reslut) {
          if (current) {
            // 选择设备需要删掉上一个的连接记录
            this.deleteConnectDeviceRecord(current, "BluetoothClose");
          }
          this.printForm.connectedBluetooth = `${val.name}`;
          this.setConnectedList(val);
          this.$message({
            message: `${val.name}打印机连接成功`,
            type: "success",
          });
          this.currentPrint = lodash.cloneDeep(val);
          // 避免已连接的无线设备获取不到的问题
          if (!val.usbName) {
            const temp = this.printList.find(
              (item) => item.address === val.address
            );
            if (!temp) {
              this.deviceAllList.push(val);
              this.filterDeviceList();
            }
          }
        } else {
          this.printForm.connectedBluetooth = ``;
          // this.setConnectedList('')
          this.$message.error(`${val.name}打印机连接失败`);
          this.currentPrint = null;
        }
        this.fullscreenLoading = false;
      } catch (error) {
        this.fullscreenLoading = false;
        console.log(error, "选中打印设备 错误信息");
      }
    },
    //进行打印
    async printEvent() {
      const printMaterialInfo = cloneDeep(this.materialInfo);
      const isDevelopment = process.env.NODE_ENV === "development";
      const isBatchMag = printMaterialInfo.materialEntity.isBatchMag;
      const materialCode = printMaterialInfo.materialEntity.code;
      const { num, batch, actualNum } = this.printForm;
      if (!actualNum) {
        Dialog.confirm({ title: "提示", message: "请填写入库数量后进行打印", confirmButtonText: "确定", cancelButtonText: "取消"});
        return;
      }
      if (!batch && isBatchMag) {
        Dialog.confirm({ title: "提示",message: "请填写批次号后进行打印",confirmButtonText: "确定",cancelButtonText: "取消"});
        return;
      }
      let willPrintData = null;
      console.log("即将请求要打印的信息,参数:","物料编码:",materialCode,"批次号:",batch,"实际数量:",actualNum,"printMaterialInfo =>",printMaterialInfo);
      try {
        willPrintData = await this.getPrintLabelTypes(materialCode, batch, actualNum);
        console.log('获取将要打印的数据信息==>',willPrintData);
      } catch (error) {
        console.log('获取将要打印的数据信息失败,即将终止打印...',error);
        Dialog.confirm({ title: "提示",message: "获取打印数据失败，请重试",confirmButtonText: "确定",cancelButtonText: "取消"});
        return;
      }
      const {code,data = {}, message } = willPrintData;
      if (code == 200) {
        const panels = data.panels.panels.map((item) => ({ ...item,command: this.printForm.printerInstruction})) || [];
        const tempList = [];
        // 打印份数大于1 需要处理数据
        if (this.printForm.num > 1) {
          // 打印格式区分
          if (this.printForm.printFormat === "AABB") {
            panels.forEach((item) => { tempList.push(...new Array(this.printForm.num).fill(item))});
          } else {
            for (let i = 0; i < this.printForm.num; i++) {
              tempList.push(...panels);
            }
          }
        } else {
          tempList.push(...panels);
        }
        console.log("即将进行打印===>","打印数据:",tempList,"打印机:",this.currentPrint);
        try {
          await Interface.hiPrint({ panels: tempList }, this.currentPrint);
        } catch (error) {
          Dialog.confirm({ title: "提示",message: "打印异常，请检查打印机后重试",confirmButtonText: "确定",cancelButtonText: "取消"});
          console.log('打印失败===> error:',error);
          return;
        }
      } else {
        Dialog.confirm({ title: "提示",message:message,confirmButtonText: "确定",cancelButtonText: "取消"});
      }
    },
    beforClosePrint(action, done) {
      if (action === "confirm") {
        // done(false)
        if (!this.show) {
          done();
        } else {
          done(false);
        }
      } else {
        done();
      }
    },
    handleCancelPrint() {
      this.printForm.num = "";
      this.show = false;
      this.$emit("handleCancelPrint");
    },
    async handleConfirmPrint() {
      const isDevelopment = process.env.NODE_ENV === "development";
      if (isDevelopment) {
        this.printEvent();
        this.$emit("handleConfirmPrint");
      }
      this.$refs["printForm"].validate(async (valid) => {
        if (valid) {
          setPrintInstruction(this.printForm.printerInstruction);
          // 判断是否存在已连接设备
          if (this.currentPrint) {
            const reslut = this.currentPrint.usbName
              ? await Interface.connectUsb(
                  this.wiredDeviceList.find(
                    (item) =>
                      item.vendorId === this.currentPrint.vendorId &&
                      item.productId === this.currentPrint.productId
                  )
                )
              : await Interface.ConnectionStatus(this.currentPrint);
            if (reslut) {
              // 已连接上打印机
              this.printEvent();
              // }else{
              //   this.MaterialPrintBarCodeRequest()
              // }

              this.$emit("handleConfirmPrint");
            } else {
              // 未连接上
              this.$message("打印设备已断开，请重新连接");
              this.printForm.connectedBluetooth = "";
              this.currentPrint = null;
              // this.setConnectedList('')
              return false;
            }
          } else {
            this.$message("请选择打印设备");
            return false;
          }
        } else {
          this.show = true;
        }
      });
    },
    getBatchCode(relateOrders, materialCode) {
      return new Promise((resolve, reject) => {
        reqBarcode(relateOrders, materialCode).then(
          (response) => {
            if (response.code === 200) {
              resolve(response.data[0]);
            }
          },
          (error) => {
            console.log("自动生成批次号api", error);
            reject();
          }
        );
      });
    },
  },
};
</script>

<style>
.el-select-dropdown.el-popper {
  z-index: 9999 !important;
}
</style>
<style lang="scss" scoped>
@import "../../../../assets/css/common.scss";
::v-deep .van-dialog__content {
  padding: 0 1.25rem !important;
}
.label-printing {
  width: 100vw;
  height: 100vh;
  background: #f5f6fa;
  display: flex;
  flex-direction: column;
  .print-btn {
    width: 170px;
    height: 83px;
    display: flex;
    align-items: center;
    justify-content: center;
    // background: #52a6fe;
    background: #ffffff;
    box-shadow: 0px 3px 6px rgba(0, 0, 0, 0.16);
    border-radius: 4px;
    font-size: 20px;
    font-family: Source Han Sans CN;
    font-weight: 400;
    color: #333333;
  }
  // 打印
  .print-dialog {
    /deep/ .van-dialog__header {
      height: 2.75rem;
      padding: 0;
      display: flex;
      align-items: center;
      justify-content: center;
      border-bottom: 1px solid #e4e4e4;
      font-size: 1.0625rem;
      font-family: Source Han Sans CN;
      font-weight: bold;
      color: #333333;
    }

    .printForm {
      .el-form-item {
        padding: 0.625rem 0;
        margin: 0;
        border-bottom: 1px solid #e4e4e4;
        /deep/ .el-input__inner {
          border: 0;
          text-align: right;
        }
        /deep/ .el-form-item__label {
          font-size: 0.9375rem;
          font-family: Source Han Sans CN;
          color: #333333;
        }
      }
    }
  }
}
</style>
